import React, { useEffect, useState } from 'react';
import './index.css';
import error from '../../assets/error.svg';
import Icon_Warning from '../../assets/Icon_Warning.svg';
import arrowIcon from '../../assets/arrowIcon.svg';
import tipIcon from '../../assets/tipIcon.svg';
import questionSuccess from '../../assets/questionSuccess.svg';
import selectIcon from '../../assets/selectIcon.svg';
import arrowIconBlue from '../../assets/arrowIconBlue.svg';
import { base64ToText, isJsonString } from '../utils/index'
import { Terminal } from 'xterm';
import EditorComponent from '../RichEditor';

const active = (props: any) => {

  // 活动对象
  const [activeValue, setActiveValue] = useState<any>({})

  const [selectKey, setSelectKey] = useState<any>([])
  const [isSubmit, setIsSubmit] = useState(false)
  const [ifSuccess, setIfSuccess] = useState<any>(undefined)//是否成功
  const [fail, setFail] = useState(false)
  const [optionAnswer, SetOptionAnswer] = useState([])
  const [tipShow, setTipShow] = useState(true)//提示框是否显示
  const [auxiliary, setAuxiliary] = useState<any>([])
  const [execExperiment, setExecExperiment] = useState(false)//是否执行完成
  const [isValidate, setIsValidate] = useState(false)//是否执行完成
  const [contValue, setContValue] = useState<any>(0)//获得的分数
  const [mark, setMark] = useState(false)
  const [localUrl, setLocalUrl] = useState<any>()
  const [validateCode, setValidateCode] = useState<any>()
  const [codePath, setCodePath] = useState<any>() //演示脚本


  // const [component, setComponent] = useState<any>(null);//mardown语法

  //是否需要连接校验
  const [ifShell, setIfShell] = useState<any>()
  // websocket实例
  const [websocket, setWebsocket] = useState<any>()
  // const [mark] = useState(false)

  const getActive = (fileId: string, workdir: boolean) => {
    let url = ''
    if (workdir) {
      url = `${localUrl}&file=${encodeURIComponent(fileId)}&workdir=${workdir}`
    } else {
      url = `${localUrl}&file=${encodeURIComponent(fileId + '.json')}`
    }
    console.log(url);

    fetch(url, {
      method: 'GET'
    })
      .then(response => response.json())
      .then(data => {
        const _data = base64ToText(data.data)
        if (!workdir) {
          setActiveValue(isJsonString(_data) ? JSON.parse(_data) : {})
        } else {
          setCodePath(_data)
        }
      })
      .catch(error => {
        console.error(error); // 处理错误
      });


  }


  //判断数组是否相同
  const areArraysEqual = (arr1: any, arr2: any) => {
    if (arr1.length !== arr2.length) {
      return false;
    }

    const set1 = new Set(arr1);
    const set2 = new Set(arr2);

    if (set1.size !== set2.size) {
      return false;
    }

    return Array.from(set1).every(item => set2.has(item));
  }

  //问答提交按钮
  const submitOption = () => {
    // console.log('🚀', '选择题')
    window.postMessage({
      type: 'markdown-reportData',
      value: {
        lang: props?.lang,
        id: isJsonString(props?.value) ? JSON.parse(props?.value)?.id ?? '' : ''
      }
    }, '*')
    const str1 = JSON.stringify(optionAnswer);
    const str2 = JSON.stringify(selectKey);
    if (!isSubmit) {
      if (!mark) {
        setIfSuccess(areArraysEqual(str1, str2))

      } else {
        if (areArraysEqual(str1, str2)) {
          setContValue(activeValue?.score ?? 0)
          ifPostContValue(activeValue?.score ?? 0)
        } else {
          ifPostContValue(0)
        }
      }
    }
    setIsSubmit(true)
  }

  //执行按钮
  const execBtn = () => {
    // console.log('🚀', '示例演示')
    window.postMessage({
      type: 'markdown-reportData',
      value: {
          lang: props?.lang,
          id: isJsonString(props?.value) ? JSON.parse(props?.value)?.id ?? '' : ''
      }
    }, '*')
    if (props?.lang === 'experiment' && !execExperiment) {
      window.postMessage({
        type: 'markdown-layout',
        value: {
          data: activeValue
        }
      }, '*')
      setExecExperiment(true)
      if (auxiliary?.length < 1) {
        setContValue(activeValue?.score ?? 0)
        ifPostContValue(activeValue?.score ?? 0)
      }
    }

  }

  //监听更新
  const updateValue = (event: any) => {
    if (event?.data?.type === 'updateActivity' && event?.data?.id === activeValue?.id) {
      getActive(event?.data?.id ?? '', false)
    }
  }

  //校验按钮
  const valitade = () => {
    // console.log('🚀', '编码测验')
    window.postMessage({
      type: 'markdown-reportData',
      value: {
          lang: props?.lang,
          id: isJsonString(props?.value) ? JSON.parse(props?.value)?.id ?? '' : ''
      }
    }, '*')
    setTimeout(() => {
      setIsValidate(true)
    }, 300);
    if (props?.lang === 'validate') {
      websocket?.send(activeValue?.code + '\r')
    } else if (auxiliary?.length > 0) {
      let code = auxiliary[0]?.code
      websocket?.send(code + '\r')
    }

  }

  //是否处于评分模式
  const ifPostContValue = (conValue: any) => {
    if (mark) {
      window.postMessage({
        type: 'postValue', value: {
          value: conValue,
          activeID: activeValue?.id
        }
      }, '*');
    }
  }


  //实验图标旋转
  const rotateImg = () => {
    let image: any

    image = document.getElementById("arrowImgBlue")
    if (image && image.style) {
      if (tipShow) {
        image.style.transform = "rotate(180deg)";
        setTipShow(!tipShow)
      } else {
        image.style.transform = "rotate(360deg)";
        setTipShow(!tipShow)
      }

    }
  }
  //提示图标旋转
  const rotateTipImg = () => {
    let image: any
    image = document.getElementById("arrowImg")

    if (image && image.style) {
      if (tipShow) {
        image.style.transform = "rotate(180deg)";
        setTipShow(!tipShow)
      } else {
        image.style.transform = "rotate(360deg)";
        setTipShow(!tipShow)
      }

    }
  }

  useEffect(() => {

    if (isJsonString(props?.value) && localUrl) {
      const elem = document.querySelector(`#${JSON.parse(props?.value)?.id}`) as HTMLElement
      if (elem?.offsetHeight > 0) {
        getActive(JSON.parse(props?.value)?.id ?? '', false)
        setIfShell(true)
      } else {
        websocket?.close()
        setIfShell(false)
      }
      // setActiveValue(JSON.parse(props?.value))
    }

  }, [props, localUrl])

  useEffect(() => {
    if (activeValue) {
      if (activeValue?.codePath) {
        getActive(activeValue?.codePath || '', true)
      }

      SetOptionAnswer(activeValue?.selected?.split(",") ?? '')
      setAuxiliary(activeValue?.auxiliary ?? [])

      if (props?.lang === 'experiment' && activeValue?.auxiliary?.length > 0) {
        setValidateCode(activeValue?.auxiliary[0]?.codeResult ?? '')
      } else {
        setValidateCode(activeValue?.codeResult ?? '')
      }

      setSelectKey([])
      setIsSubmit(false)
      setIfSuccess(false)
      setTipShow(true)
      setExecExperiment(false)
      setIsValidate(false)
      setContValue(0)
    }
  }, [activeValue])

  useEffect(() => {
    if (window.localStorage.getItem('mark') && activeValue?.id) {

      getActive(activeValue?.id ?? '', false)
      if (window.localStorage.getItem('mark') === 'true') {
        setMark(true)
      } else {
        setMark(false)
      }
    } else {
      setMark(false)
    }

  }, [window.localStorage.getItem('mark'), activeValue?.id])


  useEffect(() => {
    if (window.localStorage.getItem('activeUrl')) {
      setLocalUrl(window.localStorage.getItem('activeUrl') ?? '')
    }
  }, [window.localStorage.getItem('activeUrl')])

  useEffect(() => {
    if (props?.lang === 'question') return
    if (!props.url) return
    if (!ifShell) return
    const terminal = new Terminal()
    const ws = new WebSocket(props.url ?? "")
    setWebsocket(ws)
    let root = ''
    ws.onmessage = function (e: any) {

      let data = e.data

      if (typeof data === 'string') {
        terminal.write(data);

        if (!root) {
          root = data
          return
        }
        const _data = data.split('\r\n')
        const newData: any[] = []
        if (_data?.length > 0) {
          _data.forEach((item: any) => {
            newData.push(item.replace(/>/g, "").trim());
          })
        }
        if (newData.includes(validateCode)) {
          setIfSuccess(true)
          setContValue(activeValue?.score ?? 0)
          ifPostContValue(activeValue?.score ?? 0)
        } else {
          setFail(true)
        }
      } else {
        console.error('格式错误');
      }
    }
    return () => {
      ws?.close()
    }
  }, [props.url, validateCode, ifShell])

  useEffect(() => {
    if (!activeValue?.id) return

    window.addEventListener("message", updateValue);

    return () => {
      window.removeEventListener("message", updateValue);
    }
  }, [activeValue?.id])

  useEffect(() => {
    if (ifSuccess) {
      return
    }
    if (fail) {
      setIfSuccess(ifSuccess ?? false)
    }
  }, [ifSuccess, fail])

  return (
    <div id={isJsonString(props?.value) ? JSON.parse(props?.value)?.id ?? '' : ''} style={{ width: '100%', display: 'flex', justifyContent: 'center' }} data-start={props?.position?.start?.line ?? ''} data-end={props?.position?.end?.line ?? ''} data-page={props?.page ?? 0} className='scrollIcon'>
      <div className="activeMd">
        {props?.lang === 'question' && <div className='questionContent' data-mark={mark} data-contvalue={ifSuccess} data-required={activeValue?.required ?? false} data-requiredcorrect={activeValue?.requiredCorrect ?? false} data-submit={isSubmit}>
          <div className='questionTitle'>
            <div className='title-left' style={{ marginTop: '3px', marginRight: '10px', fontSize: '18px', color: '#333333', fontWeight: '600' }}>
              选择题
            </div>
            <div className='question-title-rigth'>
              <span style={{ display: 'inline-block' }}>
                {mark && <span style={{ display: 'inline-block' }} className='question-value'>{activeValue?.score ?? 0}分</span>}
                <span style={{ display: 'inline-block' }} className='question-type'>{activeValue?.category
                  === "checkbox" ? '多选' : '单选'}</span>
              </span>
            </div>
          </div>
          <div style={{ marginTop: '10px', fontSize: '15px', color: '#333333', fontWeight: '600', position: 'relative' }}>题目描述
            <div style={{ width: '60px', height: '4px', opacity: '0.3', background: '#1677ff', position: 'absolute', bottom: '3px' }}></div>
          </div>
          <div className='EditorClass'>
            <div className='EditorMark'></div>
            <EditorComponent value={activeValue?.title || ''} />
          </div>
          <div className='questSelect'>
            {
              activeValue?.options?.map((v: any) => <div className='questSelectitem'>
                <div className='questSelectitem-left' style={
                  {
                    border: selectKey.includes(v?.key) ? (isSubmit && !mark && activeValue?.category === 'radio' ? (ifSuccess ? '1px solid #30C213' : '1px solid #F5222D') : activeValue?.category === 'radio' ? '1px solid #1677FF' : '1px solid #fff') : '1px solid #666',
                    borderRadius: activeValue?.category === 'radio' ? '8px' : '2px'
                  }
                } onClick={() => {
                  setIsSubmit(false)
                  setContValue(0)
                  let selectValue = activeValue?.category === "checkbox" ? JSON.parse(JSON.stringify(selectKey)) : []
                  if (selectValue.includes(v?.key)) {
                    selectValue.splice(selectValue.indexOf(v?.key), 1);
                  } else {
                    selectValue.push(v?.key);
                  }
                  setSelectKey(selectValue)
                }}>
                  {
                    selectKey.includes(v?.key) && activeValue?.category === 'radio' && <div className='questSelectitem-click' style={
                      {
                        background: isSubmit && !mark && activeValue?.category === 'radio' ? ifSuccess ? ' #30C213' : '#F5222D' : "#1677FF",

                      }
                    }></div>
                  }
                  {
                    selectKey.includes(v?.key) && activeValue?.category === 'checkbox' && <div style={{ marginTop: '3px' }}>
                      <img height={17} src={selectIcon} alt="" />
                    </div>
                  }
                </div>
                <div className='questSelectitem-rigth'>
                  {v?.value}
                </div>
              </div>)
            }
            <div className='qusetion-prompt'>
              {isSubmit && !mark && (ifSuccess ? <div className='qusetion-prompt-success'>
                <img height={13} src={questionSuccess} alt="" />
                <span style={{ marginLeft: '3px' }}>回答正确</span>
              </div> : <div className='qusetion-prompt-error'>
                <img height={13} src={error} alt="" />
                <span style={{ marginLeft: '3px' }}>回答错误，请重新作答！</span>
              </div>)}
            </div>

          </div>
          {isSubmit && !ifSuccess && !mark && auxiliary?.length > 0 && auxiliary[0]?.type === 'tip' && <div className='tipContent'>
            <div style={{ display: 'flex', alignItems: 'center' }}>
              <img src={Icon_Warning} alt="" />
              <span style={{
                color: '#faad14',
                fontSize: '14px'
              }}>提示</span>
              <img id='arrowImg' src={arrowIcon} alt="" style={{ cursor: 'pointer' }} onClick={rotateTipImg} />
            </div>
            {tipShow &&
              <div className='tipValue'>
                <img src={tipIcon} alt="" className='tipIcon' />
                <div className='EditorClass'>
                  <div className='EditorMark'></div>
                  <EditorComponent value={auxiliary[0]?.description || ''} />
                </div>


              </div>
            }
          </div>}
          <div className='questionSumbit' >
            {selectKey?.length > 0 ? <div className='questionSumbit-btn' data-contValue={contValue} data-id={activeValue?.id} onClick={
              submitOption
            }>{isSubmit ? `已提交` : `${activeValue?.buttonName ?? '确认'}`}</div> : <div className='novalue-btn' >{`${activeValue?.buttonName ?? '确认'}`}</div>}
          </div>
        </div>}
        {(props?.lang === 'experiment') && <div className='experimentContent'
          data-contvalue={ifSuccess}
          data-required={activeValue?.required ?? false}
          data-requiredcorrect={activeValue?.requiredCorrect ?? false}
          data-submit={props?.lang === 'experiment' ? execExperiment : isValidate}
          data-nextrequired={activeValue?.auxiliary?.length > 0 ? activeValue?.auxiliary[0]?.required ?? false : false}
          data-nextcorrect={activeValue?.auxiliary?.length > 0 ? activeValue?.auxiliary[0]?.requiredCorrect ?? false : false}
          data-validate={isValidate}
        >
          {/* 校验指令 */}
          {<div className='validateTitle'>
            <div className='question-title-rigth'>

              <span style={{ marginRight: '10px', marginTop: '2px', fontSize: '18px', color: '#333333', fontWeight: '600' }}>{props?.lang === 'validate' ? '编码测验' : '示例演示'}</span>
              {mark && <span style={{ display: 'inline-block' }} className='question-value'>{activeValue?.score ?? 0}分</span>}
            </div>
            <div style={{ marginTop: '10px', fontSize: '15px', color: '#333333', fontWeight: '600', position: 'relative' }}>演示描述
              <div style={{ width: '60px', height: '4px', opacity: '0.3', background: '#1677ff', position: 'absolute', bottom: '3px' }}></div>
            </div>
            {/* <div style={{ marginTop: '7px', fontSize: '14px', color: '#333333', fontWeight: '500' }}><ReactMarkdown>{}</ReactMarkdown></div> */}
            <div className='EditorClass'>
              <div className='EditorMark'></div>
              <EditorComponent value={activeValue?.title} />
            </div>
            {ifSuccess !== undefined && isValidate && !mark && <div className='validate-prompt'>
              {ifSuccess ? <div className='validate-prompt-success'>
                <img height={13} src={questionSuccess} alt="" />
                <span style={{ marginLeft: '3px' }}>校验成功！</span>
              </div> : <div className='qusetion-prompt-error'>
                <img height={13} src={error} alt="" />
                <span style={{ marginLeft: '3px' }}>校验错误，请重新校验！</span>
              </div>}
            </div>}
          </div>}
          {/* 实验指令 */}
          {props?.lang === 'experiment' && activeValue?.showCode && (!execExperiment || auxiliary?.length < 1) &&
            <div className='instructTip'>
              <div style={{ display: 'flex', alignItems: 'center' }}>
                <span style={{
                  color: '#1677ff',
                  fontSize: '14px',
                  marginRight: '4px'
                }}>演示脚本</span>
                <img id='arrowImgBlue' src={arrowIconBlue} alt="" style={{ cursor: 'pointer' }} onClick={rotateImg} />
              </div>
              {tipShow &&
                <div className='instructValue'>
                  <span>{codePath ? codePath : activeValue?.code}</span>
                </div>
              }
            </div>
          }
          <div className='questionSumbit' >
            {props?.lang === 'experiment' ?
              <div>
                {execExperiment && auxiliary?.length > 0 && auxiliary[0]?.type === 'validate' && <div style={{ display: 'flex' }}>
                  <div className='last-btn' style={{ marginRight: '40px' }} onClick={() => {
                    setExecExperiment(false)
                    setIsValidate(false)
                    setIfSuccess(undefined)
                    setFail(false)
                  }}>上一步</div>
                  <div className='questionSumbit-btn' onClick={() => {
                    valitade()
                  }}>{auxiliary[0]?.buttonName || '确认'}</div>
                </div>}
                <div style={{ display: execExperiment && auxiliary?.length > 0 && auxiliary[0]?.type === 'validate' ? 'none' : 'block' }} className='exec-btn' onClick={execBtn} data-type={'exec'} data-value={JSON.stringify(activeValue)}>{activeValue?.buttonName || '确认'}</div>
              </div> : ''
            }

          </div>
        </div>}
        {(props?.lang === 'validate') && <div className='experimentContent'
          data-contvalue={ifSuccess}
          data-required={activeValue?.required ?? false}
          data-requiredcorrect={activeValue?.requiredCorrect ?? false}
          data-submit={props?.lang === 'experiment' ? execExperiment : isValidate}
          data-nextrequired={activeValue?.auxiliary?.length > 0 ? activeValue?.auxiliary[0]?.required ?? false : false}
          data-nextcorrect={activeValue?.auxiliary?.length > 0 ? activeValue?.auxiliary[0]?.requiredCorrect ?? false : false}
          data-validate={isValidate}
        >
          {/* 实验或校验题目 */}
          {/* {props?.lang !== 'validate' && (!execExperiment || auxiliary?.length < 1) && <div className='questionTitle'>
            <div className='question-title-rigth'>
              <span style={{ display: 'inline-block' }}>
                <div style={{ marginTop: '3px', marginRight: '10px', fontSize: '18px', color: '#333333', fontWeight: '500' }}>{props?.lang === 'validate' ? '编码测验' : '示例演示'}</div>
                {mark && <span style={{ display: 'inline-block' }} className='question-value'>{activeValue?.score ?? 0}分</span>}
              </span>
            </div>
          </div>}
          <div>{activeValue?.title ?? ''}</div> */}
          {/* 校验指令 */}
          {((auxiliary?.length > 0 && execExperiment) || props?.lang === 'validate') && <div className='validateTitle'>
            <div className='question-title-rigth'>

              <span style={{ marginRight: '10px', marginTop: '2px', fontSize: '18px', color: '#333333', fontWeight: '600' }}>{props?.lang === 'validate' ? '编码测验' : '示例演示'}</span>
              {mark && <span style={{ display: 'inline-block' }} className='question-value'>{activeValue?.score ?? 0}分</span>}
            </div>
            <div style={{ marginTop: '10px', fontSize: '15px', color: '#333333', fontWeight: '600', position: 'relative' }}>演示描述
              <div style={{ width: '60px', height: '4px', opacity: '0.3', background: '#1677ff', position: 'absolute', bottom: '3px' }}></div>
            </div>
            <div className='EditorClass'>
              <div className='EditorMark'></div>
              <EditorComponent value={activeValue?.title || ''} />
            </div>

            {activeValue?.ansGuide && <div style={{ marginTop: '10px', fontSize: '15px', color: '#333333', fontWeight: '600', position: 'relative' }}>答题引导
              <div style={{ width: '60px', height: '4px', opacity: '0.3', background: '#1677ff', position: 'absolute', bottom: '3px' }}></div>
            </div>}
            {activeValue?.ansGuide && <div className='EditorClass'>
              <div className='EditorMark'></div>
              <EditorComponent value={activeValue?.ansGuide || ''} />
            </div>}
            {ifSuccess !== undefined && isValidate && !mark && <div className='validate-prompt'>
              {ifSuccess ? <div className='validate-prompt-success'>
                <img height={13} src={questionSuccess} alt="" />
                <span style={{ marginLeft: '3px' }}>校验成功！</span>
              </div> : <div className='qusetion-prompt-error'>
                <img height={13} src={error} alt="" />
                <span style={{ marginLeft: '3px' }}>校验错误，请重新校验！</span>
              </div>}
            </div>}
          </div>}
          {/* 实验指令 */}
          {props?.lang === 'experiment' && activeValue?.showCode && (!execExperiment || auxiliary?.length < 1) &&
            <div className='instructTip'>
              <div style={{ display: 'flex', alignItems: 'center' }}>
                <span style={{
                  color: '#1677ff',
                  fontSize: '14px',
                  marginRight: '4px'
                }}>实验指令</span>
                <img id='arrowImgBlue' src={arrowIconBlue} alt="" style={{ cursor: 'pointer' }} onClick={rotateImg} />
              </div>
              {tipShow &&
                <div className='instructValue'>
                  <span>{activeValue?.code ?? ''}</span>
                </div>
              }
            </div>
          }
          {ifSuccess !== undefined && isValidate && !mark && !ifSuccess && (auxiliary?.length > 0 && (auxiliary[0]?.type === 'tip' || (auxiliary[0]?.auxiliary?.length > 0 && auxiliary[0]?.auxiliary[0]?.type === 'tip'))) && <div className='tipContent'>
            <div style={{ display: 'flex', alignItems: 'center' }}>
              <img src={Icon_Warning} alt="" />
              <span style={{
                color: '#faad14',
                fontSize: '14px'
              }}>提示</span>
              <img id='arrowImg' src={arrowIcon} alt="" style={{ cursor: 'pointer' }} onClick={rotateTipImg} />
            </div>
            {tipShow &&
              <div className='tipValue'>
                <img src={tipIcon} alt="" className='tipIcon' />
                <span>{props?.lang === 'validate' ? auxiliary[0]?.description ?? '' : auxiliary[0]?.auxiliary[0]?.description ?? ''}</span>
              </div>
            }
          </div>}
          <div className='questionSumbit' >
            {props?.lang === 'experiment' ?
              <div>
                {execExperiment && auxiliary?.length > 0 && auxiliary[0]?.type === 'validate' && <div style={{ display: 'flex' }}>
                  <div className='last-btn' style={{ marginRight: '40px' }} onClick={() => {
                    setExecExperiment(false)
                    setIsValidate(false)
                    setIfSuccess(undefined)
                    setFail(false)
                  }}>上一步</div>
                  <div className='questionSumbit-btn' onClick={() => {
                    valitade()
                  }}>{auxiliary[0]?.buttonName || '确认'}</div>
                </div>}
                <div style={{ display: execExperiment && auxiliary?.length > 0 && auxiliary[0]?.type === 'validate' ? 'none' : 'block' }} className='exec-btn' onClick={execBtn} data-type={'exec'} data-value={JSON.stringify(activeValue)}>{activeValue?.buttonName || '确认'}</div>
              </div> : ''
            }
            {props?.lang === 'validate' && <div className='questionSumbit-btn' onClick={() => {
              valitade()
            }}>{activeValue?.buttonName || '确认'}</div>}
          </div>
        </div>}
      </div>
    </div>

  );
};

export default active;
